Skip to content

Conversation

@WangJee
Copy link
Contributor

@WangJee WangJee commented Apr 18, 2025

The error is caused by the fact that when acquiring the profile data, the instruction at offset is PseudoCALL, but when performing profile verification, PseudoCALL is converted to AUIPC and JALR instructions, and the offset obtained is JALR; therefore, the profile data is considered invalid.

@llvmbot
Copy link
Member

llvmbot commented Apr 18, 2025

@llvm/pr-subscribers-bolt

Author: wangjue (WangJee)

Changes

The error is caused by the fact that when acquiring the profile data, the instruction at offset is PseudoCALL, but when performing profile verification, PseudoCALL is converted to AUIPC and JALR instructions, and the offset obtained is JALR; therefore, the profile data is considered invalid.


Full diff: https://github.com/llvm/llvm-project/pull/136278.diff

1 Files Affected:

  • (modified) bolt/lib/Profile/DataReader.cpp (+3)
diff --git a/bolt/lib/Profile/DataReader.cpp b/bolt/lib/Profile/DataReader.cpp
index f2e999bbfdc6d..258a36c86afb2 100644
--- a/bolt/lib/Profile/DataReader.cpp
+++ b/bolt/lib/Profile/DataReader.cpp
@@ -524,6 +524,9 @@ float DataReader::evaluateProfileData(BinaryFunction &BF,
       // when we identify tail calls, so they are still represented
       // by regular branch instructions and we need isBranch() here.
       MCInst *Instr = BF.getInstructionAtOffset(BI.From.Offset);
+      // If t's a RISCV PseudoCALL - fix it
+      if (!Instr && BC.isRISCV())
+        Instr = BF.getInstructionAtOffset(BI.From.Offset + 4);
       // If it's a prefix - skip it.
       if (Instr && BC.MIB->isPrefix(*Instr))
         Instr = BF.getInstructionAtOffset(BI.From.Offset + 1);

@WangJee
Copy link
Contributor Author

WangJee commented Apr 18, 2025

solve the issue #136276

@WangJee WangJee changed the title Fix the inaccurate profile data check [BOLT] Fix the inaccurate profile data check Apr 18, 2025
@aaupov
Copy link
Contributor

aaupov commented Apr 21, 2025

Thank you for investigating the issue.

I see that we have FixRISCVCallsPass that runs before instrumentation and replaces all calls with PseudoCALL instructions for JITLink relaxation. But the pass may replace either jalr or auipc+jalr pair with a pseudocall, so in the general case it's not correct to always adjust an offset by 4.

Comment on lines 527 to 528
// If it's a RISCV PseudoCALL - fix it
if (!Instr && BC.isRISCV())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use isRISCVCall(const MCInst &First, const MCInst &Second)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MCInst *Instr = BF.getInstructionAtOffset(BI.From.Offset);
But if this method is used, the first instruction will return nullptr, and the second instruction can correctly obtain jalr

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@aaupov Could you please review the new changes?

@WangJee
Copy link
Contributor Author

WangJee commented Apr 21, 2025

Thank you for investigating the issue.

I see that we have FixRISCVCallsPass that runs before instrumentation and replaces all calls with PseudoCALL instructions for JITLink relaxation. But the pass may replace either jalr or auipc+jalr pair with a pseudocall, so in the general case it's not correct to always adjust an offset by 4.

Thank you for your suggestion, but if it is jalr's scenario, Instr will not be nullptr?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants